/**
 * @ClassName Test
 * @Description Java SE--运算符
 * @Author 李明忠
 * @Date 2025/4/19 8:44
 * @Version 1.0
 */
public class Test {
    //条件表达式
    public static void main(String[] args) {
        int a = 10;
        int b = 20;
        boolean flag = (a > b) ? true : false;
        System.out.println(flag);//false
    }
    /**
     * 移位运算符
     * @param args
     */
    public static void main10(String[] args) {
        /*------------------------------------------------------------*/
        //左移：左侧丢弃右侧补0

        //正数：
        int a = 2;
        int b = a << 1;//a左移1位等价于 b = a 乘 2的一次方
        //如果 b = a << n 则等价于b = a 乘 2的n次方
        //注意 每一次移位并不会改变原来的值
        //他好比 b = a + 1一样a的值并不会改变
        System.out.println(a);//a值不变仍为2
        System.out.println(b);//4

        System.out.println("==============");
        //负数
        int a1 = -2;
        int b1 = a1 << 1;
        System.out.println(a1);//a值不变仍为-2
        System.out.println(b1);//-4

        //总结：
        //左移无论是正数还是负数都有*2之效


        /*------------------------------------------------------------*/
        //右移：右侧丢弃左侧补符号位(正数补0  负数补1)
        //正数
        System.out.println("==============");
        int num1 = 10;
        int num2 = num1 >> 1;
        //注意 每一次移位并不会改变原来的值
        System.out.println(num1);//num1不变为10
        System.out.println(num2);//5

        //负数
        System.out.println("==============");
        int num3 = -1;
        int num4 = num3 >> 1;
        System.out.println(num3);//1
        System.out.println(num4);//-1

        //总结
        //右移对于正数有/2之效
        //但是右移对于负数会比较尴尬，不一定有/2之效
        /*------------------------------------------------------------*/

        //无符号右移 : 右侧丢弃，左侧补0
        System.out.println("==============");
        int num6 = 10;
        int num7 = num6 >>>1;
        System.out.println(num6);//10
        System.out.println(num7);//5

    }
    /**
     * 短路问题
     * @param args
     */
    public static void main9(String[] args) {
        //对于&&
        System.out.println(10 > 20 && 10 / 0 == 0);//false

        //对于||
        System.out.println(10 < 20 || 10 / 0 == 0);//true

        //对于&
//        System.out.println(10 > 20 & 10 / 0 == 0);// 程序抛出异常

        //对于|
        System.out.println(10 < 20 | 10 / 0 == 0);// 程序抛出异常

    }
    /**
     * 位运算符
     * @param args
     */
    public static void main8(String[] args) {
        //&
        int a = 10;
        int b = 20;
        System.out.println(a & b);//0

        //|
        int a1 = 10;
        int b1 = 20;
        System.out.println(a1 | b1);//30

        //^
        int num1 = 10;
        int num2 = 0;
        System.out.println(num1 ^ num2);//10

        //~
        int num = 10;
        System.out.println(~num);//-11
    }
    /**
     * 逻辑运算符
     * @param args
     */
    public static void main7(String[] args) {
        //&& || !
        //用法
        //做分支条件
        int age = 25;
        boolean isStudent = false;
        if (age >= 18 && !isStudent) {
            System.out.println("成年人且非学生");
        }

        //循环的判断条件
        int i = 0;
        while (i < 10 && i != 5) {
            System.out.println(i);
            i++;
        }
        //防御式编程（避免空指针）
        String str = null;
        if (str != null && str.length() > 0) {  // 短路避免 NullPointerException
            System.out.println(str);
        }
        System.out.println("===============");
        //逻辑与：一假则假
        System.out.println((1 < 5) && (2 > 8));//false
        System.out.println((1 < 5) && (2 == 2));//true
        System.out.println((1 > 5) && (2 < 8));//false
        System.out.println((1 > 5) && (2 > 8));//false

        System.out.println("=====================");
        //表达式为关系表达式
        System.out.println((2 == 2) && (3 > 3));//false
        //表达式为布尔值
        System.out.println(false || true);//true
        //表达式为逻辑表达式
        System.out.println((!(2 == 2) && (3 > 3)));//true

        System.out.println("===============");
        //逻辑或：一真则真
        System.out.println((1 < 5) || (2 > 8));//true
        System.out.println((1 < 5) || (2 == 2));//true
        System.out.println((1 > 5) || (2 < 8));//true
        System.out.println((1 > 5) || (2 > 8));//false

        System.out.println("===============");
        //逻辑非！
        System.out.println(!true);//false
        System.out.println(!(1 == 1));//false
    }
    /**
     * 关系运算符
     * @param args
     */
    public static void main6(String[] args) {
        //在Java中不能连着写
        int a = 4;
//        System.out.println(3 < a < 5);//编译报错
        //错误信息：
        // java: 二元运算符 '<' 的操作数类型错误
        // 第一个类型:  boolean
        // 第二个类型: int

        //关系运算符的适用类型
        //数值类型（byte, short, int, long, float, double）
        // 可以用于所有关系运算符（==, !=, >, <, >=, <=）
        int num1 = 10;
        int num2 = 20;
        System.out.println(num1 == num2);//false

        //对于浮点数我们不建议比较：因为浮点数在底层就有精度问题
        //eg1:如果你浮点数是经过计算的那么底层是为无法求出精确值并存储的
        double num3 = 0.1 + 0.2;//num3并不是0.3而是0.30000000000000004
        System.out.println(num3 == 0.3);//false

        //eg2:如果你只是将0.3存储而不进行运算，那么编译器会将其转换为最接近的二进制表示，
        // 而 0.3 的二进制表示在比较时可能会与字面量 0.3 的二进制表示相同
        //但只是可能而已
        //因此不建议使用浮点数进行比较大小
        double num4 = 0.3;
        System.out.println(num4 == 0.3);//true

        //字符型
        char c1 = 'A', c2 = 'B';
        System.out.println(c1 < c2); // true（'A'的Unicode值65 < 'B'的66）

        //布尔类型之时支持== !=
        boolean flag1 = true, flag2 = false;
        System.out.println(flag1 == flag2); // false

        System.out.println("============");
        //对象的比较
        String str1 = "hello";
        String str2 = new String("hello");
        //对象的比较==和!=比较的是地址
        System.out.println(str1 == str2);//false
        System.out.println(str1 != str2);//true
    }
    /**
     * 自增/自减
     * @param args
     */
    public static void main5(String[] args) {
        //自减
        //后置-- 先赋后自减
        int a = 10;
        int b = 10;
        b = a--;
        //b = a     ==> b = 10
        //a = a - 1; ==> a = 9
        System.out.println(b);//10
        System.out.println(a);//9
        System.out.println("==============");

        //前置-- 先自减后赋
        int a1 = 10;
        int b1 = 10;
        b1 = --a1;
        //a1 = a1 - 1 ==> a1 = 9
        //b1 = a1    ==> b1 = 9
        System.out.println(b1);//9
        System.out.println(a1);//9
        System.out.println("==============");

        //自增
        //后置++ 先赋后自增
        int a2 = 10;
        int b2 = 10;
        b2 = a2++;
        //b2 = a2      ==>b2 = 10
        //a2 = a2 + 1; ==> a2 = 11
        System.out.println(b2);//10
        System.out.println(a2);//11
        System.out.println("==============");

        //前置++ 先自增后赋
        int a3 = 10;
        int b3 = 10;
        b3 = ++a3;
        //a3 = a3 + 1  ==》a3 = 11
        //b3 = a3      ==> b3 = 11
        System.out.println(b3);//11
        System.out.println(a3);//11

    }
    /**
     * 符合运算符的特性
     * @param args
     */
    public static void main4(String[] args) {
        //对于相同类型的不会发生自动转型
        //1.int
        int a = 10;
        int b = 0;
        b += a;//<==>b = b + a;
        //int型的+int型的a结果赋给int型b没有问题
        System.out.println(b);//10

        //对于不同类型会发生自动转型
        //eg1:
        byte num1 = 100;
        num1 += 28;//num1 += 28 <==> num1 = num1 + 28;
        System.out.println(num1);//-128

//        byte num1 = 100;
//        num1 = (byte)(num1 + 28);

    }
    /**
     * 增量运算符
     * @param args
     */
    public static void main3(String[] args) {
        //浮点数
        double y = 10.0;
        System.out.println(y /= 3.0);// y = y / 3.0 → 3.3333333333333335
        System.out.println( y %= 2.0);// y = y % 2.0 → 1.3333333333333335

        System.out.println("=============");
        //字符型
        char c = 'A';
        System.out.println(c += 1);//B

        System.out.println("=============");
        //字符串
        String str = "hello ";
        //str+="world"<===>str = str + "world"
        System.out.println(str += "world");//hello world
        /*
         * 例如：
         *
         * byte b = 100;
         * b += 50; // 相当于 b = (byte)(b + 50)，即使 b + 50 是 int，
         *也会强制转换回 byte
         * System.out.println(b); // -106（因为 byte 溢出）
         * 而直接使用 b = b + 50 会编译错误，因为 b + 50 是 int，不能直接赋值给 byte：
         *
         * byte b = 100;
         * b = b + 50; // 编译错误！需要显式强制转换：b = (byte)(b + 50)
         */


    }
    /**
     * 四则运算符
     * @param args
     */
    public static void main2(String[] args) {
//        int a = 10;
//        int b = 20;
//
//        //+
//        System.out.println(a + b);//30
//        //-
//        System.out.println(a - b);//-10
//        //*
//        System.out.println(a * b);//200

        //除号
        int num1 = 40;
        int num2 = 30;
        // int/int 值为int 而且会向下取整
        //什么是向取整呢？ ==》 eg：12.4向下取整为12
        System.out.println(num1 / num2);//1

        int num3 = 3;
        int num4 = 2;
        //结果为什么不是1.5？而是1
        //int/int 结果为整型所以他向下取整了（也就是保留整数,去带息小数）
        System.out.println(num3 / num4);//1

        //如果想要的到1.5则我们只需要将其中一个数字变为double 即可
        //如何变呢？
        double sum = num3*1.0 / num4;
        System.out.println(sum);//1.5

        //取模
        int a = 10;
        int b = 4;

        //首先a/b=2……2
        //因此a%b就是2
        System.out.println(a % b);//2
        System.out.println("=============");

        //取模操作符的结果符号
        System.out.println(-10 % -3);//-1
        System.out.println(-10 % 3);//-1
        System.out.println(10 % 3);//1
        System.out.println(10 % -3);//1
        //观察可知：结果的符号取决与左侧的操作数符号

        //取模运算符也可对double类型进行取模，但是没有意义
        System.out.println(11.5 % 2.0);//结果：1.5

        //除/和取模%运算符右操作数不能为0
        int a1 = 10;
        int b1 = 0;
        int c1 = a1 / b1;
        System.out.println(c1);//出现异常
    }
    /**
     * 什么是运算符
     * @param args
     */
    public static void main1(String[] args) {
        int b = 20;
        int a = 10;

        //比如运算符：加
        int c = a + b;

        //比如运算符：<
        boolean flag = a < b;
    }
}
